﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

#endregion
using System.Reflection;
using System.Reflection.Emit;
namespace Ndo
{
    [Flags]
    internal enum ARW { None = 0x0, Avoid = 0x1, Reader = 0x2, Writer = 0x4 }
    internal sealed class BoxHelper
    {
        static int id;
        internal static int GetId()
        {
            return System.Threading.Interlocked.Increment(ref id);
        }
        private BoxHelper() 
        { }
        static BoxHelper()
        {
            ThreadEnterMethod = typeof(System.Threading.Monitor).GetMethod("Enter");
            ThreadExitMethod = typeof(System.Threading.Monitor).GetMethod("Exit");

            WriterEnterMethod = typeof(System.Threading.ReaderWriterLock).GetMethod("AcquireWriterLock", new Type[] { typeof(int) });
            WriterExitMethod = typeof(System.Threading.ReaderWriterLock).GetMethod("ReleaseWriterLock");

            ReaderEnterMethod = typeof(System.Threading.ReaderWriterLock).GetMethod("AcquireReaderLock", new Type[] { typeof(int) });
            ReaderExitMethod = typeof(System.Threading.ReaderWriterLock).GetMethod("ReleaseReaderLock");

            
            ObjectConstructor = typeof(object).GetConstructor(BoxHelper.EmptyTypes);
            ObjectGetTypeMethod = typeof(object).GetMethod("GetType");
            AssemblyName asmName = new AssemblyName("BoxAssembly");
            BoxAssemblyBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);
            BoxModuleBuilder = BoxAssemblyBuilder.DefineDynamicModule("BoxModule");
        }
        internal static readonly MethodInfo ThreadEnterMethod;
        internal static readonly MethodInfo ThreadExitMethod;

        internal static readonly MethodInfo WriterEnterMethod;
        internal static readonly MethodInfo WriterExitMethod;

        internal static readonly MethodInfo ReaderEnterMethod;
        internal static readonly MethodInfo ReaderExitMethod;

        internal static readonly MethodInfo CurrentMethodGetter = typeof(MethodBase).GetMethod("GetCurrentMethod");
        internal static readonly ConstructorInfo ObjectConstructor;
        internal static readonly MethodInfo ObjectGetTypeMethod;
        internal static readonly AssemblyBuilder BoxAssemblyBuilder;
        internal static readonly ModuleBuilder BoxModuleBuilder;
        internal static readonly Type[] EmptyTypes = new Type[0];
        internal const BindingFlags AllMemberBindingFlags = BindingFlags.Public | BindingFlags.Instance;
        internal const MethodAttributes InterfaceMethodAttribute =
            MethodAttributes.Private |
            MethodAttributes.NewSlot |
            MethodAttributes.HideBySig |
            MethodAttributes.Final |
            MethodAttributes.Virtual;
        internal const FieldAttributes PrivateFieldAttribute =
            FieldAttributes.Private |
            FieldAttributes.InitOnly;
        internal const FieldAttributes PrivateStaticFieldAttriute =
            FieldAttributes.Private |
            FieldAttributes.Static;
        internal static Type[] GetParamsTypes(ParameterInfo[] parms)
        {
            Type[] ts = new Type[parms.Length];
            for (int i = parms.Length - 1; i >= 0; i--)
            {
                ts[parms[i].Position] = parms[i].ParameterType;
            }
            return ts;
        }

        internal static Type[] GetParamsTypes(PropertyInfo pi)
        {
            try
            {
                return GetParamsTypes(pi.GetIndexParameters());
            }
            catch{}
            return EmptyTypes;
        }

    }
}
